#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <sys/prctl.h>

#define DBG_PRINT(fmt, args...) {printf("%s ", __FUNCTION__);printf(fmt,##args);}

#define BUFFER_LEN 0x4000
void *testThead1(void* arg)
{
    //设定线程名为zoobiTask1
    prctl(PR_SET_NAME, "zoobiTask1");

    char buffer[BUFFER_LEN];

    DBG_PRINT("Start\n");
    sleep(3);
    DBG_PRINT("End\n");
    exit(0);
}

#define THREAD_STACK_LEN 0x4000
int main(int argc, const char* argv[])
{
    pthread_t thread1ID;
    pthread_attr_t attr;

    int ret = 0;
    void *stackAddr = NULL;
    //获取linux的页大小
    int paseSize = getpagesize();

    DBG_PRINT("The linux page size:0x%x\n", paseSize);

    pthread_attr_init(&attr);
    /**
     * 申请内存，并且内存以页大小对齐，需要申请的内存大小必须是2的整数次幂;
     * 经常用的malloc申请的内存只会默认使用8bytes或者16bytes对齐(依赖平台是32位还是64位);
     */
    ret = posix_memalign(&stackAddr, paseSize, THREAD_STACK_LEN);
    if(0 != ret)
    {
        DBG_PRINT("posix_memalign failed, errno:%s\n", strerror(ret));
        return -1;
    }
#if 1
    /**
     * 设定线程运行栈地址和大小，栈大小最小为16KB，并且栈地址以页面对齐;
     */
    ret = pthread_attr_setstack(&attr, stackAddr, THREAD_STACK_LEN);
    if(0 != ret)
    {
        DBG_PRINT("pthread_attr_setstack failed, errno:%s\n", strerror(ret));
        return -1;
    }
#endif
    void *getstackaddr = NULL;
    size_t getstackSize = 0;
    pthread_attr_getstack(&attr, &getstackaddr, &getstackSize);
    DBG_PRINT("getstackaddr:%p, getstackSize:0x%x\n", getstackaddr, getstackSize);

    ret = pthread_create(&thread1ID, &attr, testThead1, NULL);
    if(ret != 0)
    {
        DBG_PRINT("pthread_create failed! errno:%s\n", strerror(ret));
        return -1;
    }
    pthread_detach(thread1ID);

    sleep(5);
    printf("thread done! \n");
    return 0;
}
